/**********************************************************************

  Audacity: A Digital Audio Editor

  EffectEditor.h

  Dominic Mazzoni
  Vaughan Johnson
  Martyn Shaw

  Paul Licameli split from EffectPlugin.h

**********************************************************************/
#ifndef __AUDACITY_EFFECT_EDITOR__
#define __AUDACITY_EFFECT_EDITOR__

#include "Observer.h"
#include <wx/event.h>

class EffectSettingsAccess;
class EffectUIServices;
class wxWindow;

//! Message sent by EffectEditor when a setting is changed by the user
struct EffectSettingChanged final
{
    size_t index { size_t(-1) };
    float newValue {};
};

class AUDACITY_DLL_API EffectEditor /* not final */ : public Observer::Publisher<EffectSettingChanged>
{
public:
    EffectEditor(
        const EffectUIServices& services, EffectSettingsAccess& access);

    virtual ~EffectEditor();

    //! Get settings data from the panel; may make error dialogs and return false
    /*!
     @return true only if panel settings are acceptable
     */
    virtual bool ValidateUI() = 0;

    //! Update appearance of the panel for changes in settings
    /*!
     Default implementation does nothing, returns true

     @return true if successful
     */
    virtual bool UpdateUI();

    /*!
     Default implementation returns false
     @return true if using a native plug-in UI, not widgets
     */
    virtual bool IsGraphicalUI();

    //! On the first call only, may disconnect from further event handling
    /*!
     Default implemantation does nothing
     */
    virtual void Disconnect();

    /*!
     Handle the UI OnClose event.
     Default implementation calls mUIServices.CloseUI()
    */
    virtual void OnClose();

    //! Enable or disable the Apply button of the dialog that contains parent
    static bool EnableApply(wxWindow* parent, bool enable = true);

    // id that should be used by preview play button of effect dialog
    static constexpr int kPlayID = 20102;

    //! Enable or disable the preview play button of the dialog that contains
    //! parent
    static bool EnablePreview(wxWindow* parent, bool enable = true);

protected:
    // Convenience function template for binding event handler functions
    template<typename EventTag, typename Class, typename Event>
    void BindTo(
        wxEvtHandler& src, const EventTag& eventType, void (Class::*pmf)(Event&))
    {
        src.Bind(eventType, pmf, static_cast<Class*>(this));
    }

    const EffectUIServices& mUIServices;
    EffectSettingsAccess& mAccess;

    bool mUIClosed { false };
};
#endif
